home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / games / IndiZone / cycles / draw.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  17.9 KB  |  881 lines

  1. /*
  2.  * all the gl drawing routines
  3.  */
  4.  
  5. #include <gl/device.h>
  6. #include <stdio.h>
  7. #include <bstring.h>    /* for bcopy */
  8. #include <stdlib.h>    /* for rand, RAND_MAX */
  9. #include <math.h>    /* for cos, sin, M_PI */
  10. #include "cycles.h"
  11.  
  12. #define MAX(x, y) ((x)>(y)?(x):(y))
  13.  
  14. extern Object tail_obj, engine_obj, chassis_top, back_stuff[LEVELS];
  15. extern float speed_fac, vec[4][2];
  16. extern CYCLE *good, bike[CYCLES];
  17. extern int used[CYCLES], solo;
  18. extern Matrix idmat;
  19.  
  20. #ifdef RGB_MODE
  21. int trail_col[COLOURS] = { 0xffff00, 0xff00ff, 0x00ffff, 0x55ff00, 0xff5500, 0x5500ff };
  22. int level_col[LEVELS]  = { 0xff4444, 0x44cc44, 0x4444ff };
  23. #else
  24. int trail_col[COLOURS] = { 102, 103, 104, 105, 106, 107 };
  25. int level_col[LEVELS]  = { BLUE, GREEN, RED };
  26. #endif
  27.  
  28. CYCLE start_pos[CYCLES];
  29. static float start_angle[CYCLES], spin[CYCLES];
  30.  
  31. /* robin's soundtrack of choice is Velocity Girl */
  32.  
  33.  
  34. void drawgrid(int level, int look_offset) {
  35.     /* do crude clipping */
  36.     if (((good->vec_ptr + look_offset)%4) || good->falling != 0)
  37.     callobj(back_stuff[level]);
  38.     draw_coloured_grid(level);
  39. }
  40.  
  41.  
  42. /* draws the trail of Cycle C,  will also handle a falling wall of a dead cycle */
  43. void drawtrail(CYCLE *C, int draw_level) {
  44.     register int i;
  45.     int segment;
  46.     float v[3];
  47.     float height;
  48.  
  49. #ifdef DEBUG
  50. printf("trail:\n");
  51. #endif
  52.  
  53.     height = TRAIL_HEIGHT - TRAIL_HEIGHT*(C->fall)/WALL_FALL;
  54.  
  55.     /*
  56.      * draw all but the 1st trail element
  57.      */
  58.     segment = 0;
  59.     i = C->trail_ptr;
  60. #ifdef RGB_MODE
  61.     cpack(trail_col[C->trail_colour]);
  62. #else
  63.     color(trail_col[C->trail_colour]);
  64. #endif
  65.     if (C->fall < WALL_FALL) {
  66.     do {
  67.         if (C->trail[i].level == draw_level) {
  68.         if (!segment) {
  69.             segment = 1;
  70.             bgntmesh();
  71.         }
  72.         v[0] = C->trail[i].x;
  73.         v[1] = 0.0;
  74.         v[2] = C->trail[i].z;
  75.         v3f(v);
  76.         v[1] = height;
  77.         v3f(v);
  78.         }
  79.         else if (segment) {
  80.         segment = 0;
  81.         endtmesh();
  82.         }
  83.         i = (i - 1 + TRAIL_LENGTH) % TRAIL_LENGTH;
  84. #ifdef DEBUG
  85. printf(" %d", i);
  86. #endif
  87.     } while(i != C->trail_ptr && C->trail[i].level != -1);
  88.     if (segment) endtmesh();
  89.  
  90. #ifdef DEBUG
  91. printf("\n");
  92. #endif
  93.  
  94.     /*
  95.      * draw the 1st trail element from the bike to the last corner
  96.      */
  97.     i = C->trail_ptr;
  98.     v[1] = 0.0;
  99.     if (C->trail[i].level == draw_level && MAX(ABS(C->trail[i].x - C->origin.x), ABS(C->trail[i].z - C->origin.z)) > CYCLE_TAIL) {
  100.         bgnpolygon();
  101.         v[0] = C->trail[i].x;
  102.         v[2] = C->trail[i].z;
  103.         v3f(v);
  104.         v[1] = height;
  105.         v3f(v);
  106. #if defined(SHADING) && defined(RGB_MODE)
  107.         cpack(0xffffff);
  108. #endif
  109.         v[0] = C->origin.x - CYCLE_TAIL*vec[C->vec_ptr][0];
  110.         v[2] = C->origin.z - CYCLE_TAIL*vec[C->vec_ptr][1];
  111.         v3f(v);
  112.         v[1] = 0.0;
  113.         v3f(v);
  114.         endpolygon();
  115.     }
  116.     }
  117.  
  118.     /*
  119.      * do it all again, but for lines on top and bottom
  120.      */
  121. #ifdef RGB_MODE
  122.     cpack(0xffffff);
  123. #else
  124.     color(WHITE);
  125. #endif
  126.  
  127.     if (C->fall < WALL_FALL) {
  128.  
  129.     /*
  130.      * don't zbuffer the top line 'cos it flickers...
  131.      * unless it's below eye level in which case we have to
  132.      */
  133.     if (C->falling == 0) zbuffer(FALSE);
  134.  
  135.     /*
  136.      * all but 1st trail element
  137.      */
  138.     segment = 0;
  139.     i = C->trail_ptr;
  140.     v[1] = height;
  141.     do {
  142.         if (C->trail[i].level == draw_level) {
  143.         if (!segment) {
  144.             segment = 1;
  145.             bgnline();
  146.         }
  147.         v[0] = C->trail[i].x;
  148.         v[2] = C->trail[i].z;
  149.         v3f(v);
  150.         }
  151.         else if (segment) {
  152.         segment = 0;
  153.         endline();
  154.         }
  155.         i = (i - 1 + TRAIL_LENGTH) % TRAIL_LENGTH;
  156.     } while(i != C->trail_ptr && C->trail[i].level != -1);
  157.     if (segment) endline();
  158.  
  159.     /*
  160.      * 1st trail: from bike to 1st corner
  161.      */
  162.     i = C->trail_ptr;
  163.     v[1] = height;
  164.     if (C->trail[i].level == draw_level && MAX(ABS(C->trail[i].x - C->origin.x), ABS(C->trail[i].z - C->origin.z)) > CYCLE_TAIL) {
  165.         bgnline();
  166.         v[0] = C->trail[i].x;
  167.         v[2] = C->trail[i].z;
  168.         v3f(v);
  169.         v[0] = C->origin.x - CYCLE_TAIL*vec[C->vec_ptr][0];
  170.         v[2] = C->origin.z - CYCLE_TAIL*vec[C->vec_ptr][1];
  171.         v3f(v);
  172.         endline();
  173.     }
  174.  
  175.     if (C->falling == 0) zbuffer(TRUE);
  176.  
  177.     /* upright line segments */
  178.     if (C->trail[i].level == draw_level) {
  179.         linewidth(2);
  180.  
  181.         i = C->trail_ptr;
  182.         do {
  183.         if (C->trail[i].level == draw_level) {
  184.             v[0] = C->trail[i].x;
  185.             v[2] = C->trail[i].z;
  186.             bgnline();
  187.             v[1] = height;
  188.             v3f(v);
  189.             v[1] = 0.0;
  190.             v3f(v);
  191.             endline();
  192.         }
  193.         i = (i - 1 + TRAIL_LENGTH) % TRAIL_LENGTH;
  194.         } while(i != C->trail_ptr && C->trail[i].level != -1);
  195.  
  196.         linewidth(1);
  197.     }
  198.     }
  199. }
  200.  
  201.  
  202. /* Draws cycle C in its C->origin point */
  203. void drawcycle(CYCLE *C, int level, int look_offset) {
  204.     float dir;
  205.     int dirx, dirz, lo_res;
  206.  
  207.     if (C->level != level) return;
  208.  
  209.     /* do crude clipping - behind us so don't draw */
  210.     if (C != good && good->falling == 0) {
  211.     /* one of these will be zero, return if both at 0 */
  212.     dirx = (vec[(good->vec_ptr + look_offset)%4][0]*(C->origin.x - good->origin.x) > 0);
  213.     dirz = (vec[(good->vec_ptr + look_offset)%4][1]*(C->origin.z - good->origin.z) > 0);
  214.     if (!(dirx || dirz)) return;
  215.     }
  216.  
  217.     pushmatrix();
  218.     /* have a simple algorithm if just running around on the grid */
  219.     if (C->falling == 0)
  220.     dir = 90.0*(float)C->vec_ptr;
  221.     else
  222.     dir = -atan2(C->direction.z, C->direction.x)*180.0/M_PI - 90.0;
  223.  
  224.     /* set lo res or high res mode for wheel drawing */
  225.     lo_res = 0;
  226.     if (speed_fac > 1.5) lo_res = 1;
  227.  
  228.     translate(C->origin.x, C->origin.y - HEIGHT, C->origin.z);
  229.     rot(dir, 'y');
  230.     translate(0.0, 0.0, -0.5 + CYCLE_VIEW_PT);
  231.     draw_cycle(C->id, C->step, C->trail_colour, lo_res, C->type, bike[C->owner].trail_colour);
  232.     popmatrix();
  233. }
  234.  
  235.  
  236. /*
  237.  * If C->fall > 0 this routine explodes a badguy cycle
  238.  */
  239. void explode(CYCLE *C, int level) {
  240.     float dir;
  241.     float dying;
  242.  
  243.     if (C->level != level) return;
  244.  
  245.     dying = C->fall*100.0/WALL_FALL;
  246.  
  247.     if (C->fall < WALL_FALL) {
  248.     if (solo) {
  249.         if (dying != 0.0) C->jump_speed = 2*JUMP_POWER;
  250.         C->origin.y += C->jump_speed;
  251.         C->jump_speed -= GRAVITY;
  252.         if (C->origin.y < HEIGHT) C->fall = WALL_FALL;
  253.     }
  254.     else {
  255.             C->origin.y *= 3.0;
  256.     }
  257.  
  258.     pushmatrix();
  259.     dir = 90.0*(float)C->vec_ptr;
  260.     translate(C->origin.x, C->origin.y - HEIGHT, C->origin.z);
  261.     rot(dir, 'y');
  262.     translate(0.0, 0.0, -0.5);
  263.  
  264.         callobj(chassis_top);
  265.  
  266.     pushmatrix();
  267.     translate(dying, 0.3*C->origin.y, -dying);
  268.         callobj(tail_obj);
  269.     popmatrix();
  270.  
  271.     pushmatrix();
  272.     translate(0.5*dying, 0.3*C->origin.y, dying);
  273.         callobj(engine_obj);
  274.     popmatrix();
  275.  
  276.     pushmatrix();
  277.     translate(dying, C->origin.y, -dying);
  278.     draw_wheel(0);
  279.     popmatrix();
  280.  
  281.     pushmatrix();
  282.     translate(dying, 1.5, -4.0 + dying);
  283.     draw_wheel(0);
  284.     popmatrix();
  285.  
  286.     popmatrix();
  287.     }
  288. }
  289.  
  290.  
  291. void explode_me(CYCLE *C) {
  292.     float dying, scaled_step;
  293.     double cx, sx;
  294.     static double angle, dir;
  295.  
  296.     dying = C->fall/WALL_FALL;
  297.  
  298.     if (C->fall < WALL_FALL) {
  299.     if (C->falling == 1) {
  300.         angle = -(float)(C->vec_ptr + 1)*0.5*M_PI;
  301.         dir = ((double)rand()/(double)RAND_MAX - 0.5);
  302.     }
  303.     scaled_step = C->step*speed_fac;
  304.  
  305.     /* change height */
  306.         C->origin.y += 0.5*scaled_step*JUMP_POWER*(0.6 - dying);
  307.  
  308.     /* change direction */
  309.     angle += dir*3.0*M_PI*speed_fac/(double)WALL_FALL;
  310.     cx = cos(angle);
  311.     sx = sin(angle);
  312.     C->direction.x = cx;
  313.     C->direction.y = -0.7*dying;
  314.     C->direction.z = sx;
  315.     }
  316. }
  317.  
  318.  
  319. /*
  320.  * save the initial position of the cycle so that we can
  321.  * tumble down to it and restore it properly and then move C
  322.  * to the initial position for falling
  323.  */
  324. void init_tumble(CYCLE *C) {
  325.     double angle;
  326.  
  327.     bcopy((void *)C, (void *)&start_pos[C->id], sizeof(CYCLE));
  328.  
  329.     /* setup to match the stuff in tumble_down */
  330.     C->fall = -IN_TUMBLE;
  331.     C->falling = -10000;
  332.     C->origin.x = 0.0;
  333.     C->origin.y = TUMBLE_HEIGHT;
  334.     C->origin.z = 0.0;
  335.  
  336.     start_angle[C->id] = -(float)(C->vec_ptr + 1)*0.5*M_PI;
  337.     spin[C->id] = (float)rand()/(float)RAND_MAX < 0.5 ? -1.0 : 1.0;
  338.  
  339.     /* change direction - must match with the below */
  340.     angle = spin[C->id]*0.75*M_PI + start_angle[C->id];
  341.     C->direction.x = cos(angle);
  342.     C->direction.y = -3.0;
  343.     C->direction.z = sin(angle);
  344.  
  345.     C->view = vadd(C->origin, C->direction);
  346. }
  347.  
  348.  
  349. /*
  350.  * handle the starting tumble down onto the grid
  351.  */
  352. void tumble_down(CYCLE *C) {
  353.     float fallfact;
  354.     double angle;
  355.  
  356.     C->fall += speed_fac;
  357.     if (C->fall > 0.0) {
  358.     C->fall = 0.0;
  359.     C->falling = 0;
  360.     }
  361.  
  362.     fallfact = -(C->fall)/IN_TUMBLE; /* 1 at start, 0 when down on grid */
  363.  
  364.     /* interp origin between high central point and final */
  365.     C->origin.x = (1.0 - fallfact)*start_pos[C->id].origin.x;
  366.     C->origin.z = (1.0 - fallfact)*start_pos[C->id].origin.z;
  367.     C->origin.y = fallfact*TUMBLE_HEIGHT + (1.0 - fallfact)*HEIGHT;
  368.  
  369.     /* change direction */
  370.     angle = spin[C->id]*0.75*M_PI*fallfact + start_angle[C->id];
  371.     C->direction.x = cos(angle);
  372.     C->direction.y = -3.0*fallfact;
  373.     C->direction.z = sin(angle);
  374.  
  375.     /* restore initial state... */
  376.     if (C->falling == 0)
  377.     bcopy((void *)&start_pos[C->id], (void *)C, sizeof(CYCLE));
  378. }
  379.  
  380.  
  381. #ifdef SHOW_TIMING
  382. void show_time(double frame_time, float min) {
  383.     char pic_time_str[128];
  384.  
  385.     zbuffer(FALSE);
  386. #ifdef RGB_MODE
  387.     cpack(0x00ff00);
  388. #else
  389.     color(GREEN);
  390. #endif
  391.     cmov(-3.0, 1.0, -2.0);
  392.     sprintf(pic_time_str, "id: %d level: %d frames/sec: %.2g speed fac:%.2g min: %.2g bhv: %d, %s",
  393.      good->id, good->level, (float)(1.0/frame_time), speed_fac, min, good->behave, good->type==PERSON?"P":"R");
  394.     charstr(pic_time_str);
  395.     zbuffer(TRUE);
  396. }
  397. #endif
  398.  
  399.  
  400. void write_player_list(float x, float y,  float y_off) {
  401.     int i;
  402.  
  403.     for (i = 0; i < CYCLES; i++) {
  404.     if (used[i] && bike[i].alive) {
  405.         /* write level patch */
  406. #ifdef RGB_MODE
  407.         cpack(level_col[bike[i].level]);
  408. #else
  409.         color(level_col[bike[i].level]);
  410. #endif
  411.         rectf(x, y, x-0.5*y_off, y-0.8*y_off);
  412.  
  413.         /* write up R in owner colour if it's there */
  414.         if (bike[i].type == ROBOT) {
  415. #ifdef RGB_MODE
  416.         cpack(trail_col[bike[bike[i].owner].trail_colour]);
  417. #else
  418.         color(trail_col[bike[bike[i].owner].trail_colour]);
  419. #endif
  420.         cmov2(x-y_off, y);
  421.         if (bike[i].behave)
  422.             charstr("R+");
  423.         else
  424.             charstr("R");
  425.         }
  426.  
  427.         /* write player name */
  428.         if (bike[i].falling > 0)
  429. #ifdef RGB_MODE
  430.         cpack(0xffffff);
  431. #else
  432.         color(WHITE);
  433. #endif
  434.         else
  435. #ifdef RGB_MODE
  436.         cpack(trail_col[bike[i].trail_colour]);
  437. #else
  438.         color(trail_col[bike[i].trail_colour]);
  439. #endif
  440.         cmov2(x-2*y_off, y);
  441.         charstr(bike[i].name);
  442.         y += y_off;
  443.     }
  444.     }
  445. }
  446.  
  447.  
  448. void draw_info(int look_offset, int help_mode, float min, int pts, int big_kills, int trail_kills) {
  449.     float speed, v[2];
  450.     short speed255;
  451.     char junk[64];
  452.     static int min_colour = 0;
  453.  
  454.     zbuffer(FALSE);
  455.     mmode(MVIEWING);
  456.     ortho2(0.0, 1.0, 0.0, 1.0);
  457.  
  458.     if (!look_offset && good->falling == 0) {
  459.     /* draw a little instrument backdrop thing */
  460. #ifdef RGB_MODE
  461.     cpack(GREY25);
  462. #else
  463.     color(GREY25);
  464. #endif
  465.     bgnpolygon();
  466.     v[0] = 0.5 - 0.2;
  467.     v[1] = 0.0;
  468.     v2f(v);
  469.     v[0] = 0.5 - 0.18;
  470.     v[1] = 0.07;
  471.     v2f(v);
  472. #if defined(SHADING) && defined(RGB_MODE)
  473.     cpack(GREY50);
  474. #endif
  475.     v[0] = 0.5 - 0.13;
  476.     v[1] = 0.14;
  477.     v2f(v);
  478.     v[0] = 0.5 + 0.13;
  479.     v[1] = 0.14;
  480.     v2f(v);
  481. #if defined(SHADING) && defined(RGB_MODE)
  482.     cpack(GREY25);
  483. #endif
  484.     v[0] = 0.5 + 0.18;
  485.     v[1] = 0.07;
  486.     v2f(v);
  487.     v[0] = 0.5 + 0.2;
  488.     v[1] = 0.0;
  489.     v2f(v);
  490.     endpolygon();
  491.  
  492.     /* and draw a border around the console */
  493. #ifdef RGB_MODE
  494.     cpack(0xffffff);
  495. #else
  496.     color(WHITE);
  497. #endif
  498.     bgnclosedline();
  499.     v[0] = 0.5 - 0.2;
  500.     v[1] = 0.0;
  501.     v2f(v);
  502.     v[0] = 0.5 - 0.18;
  503.     v[1] = 0.07;
  504.     v2f(v);
  505.     v[0] = 0.5 - 0.13;
  506.     v[1] = 0.14;
  507.     v2f(v);
  508.     v[0] = 0.5 + 0.13;
  509.     v[1] = 0.14;
  510.     v2f(v);
  511.     v[0] = 0.5 + 0.18;
  512.     v[1] = 0.07;
  513.     v2f(v);
  514.     v[0] = 0.5 + 0.2;
  515.     v[1] = 0.0;
  516.     v2f(v);
  517.     endclosedline();
  518.  
  519.     /* interp between blue and red */
  520.     speed = good->step/MAX_STEP;
  521.     speed255 = speed*255;
  522.  
  523. #ifndef RGB_MODE
  524.     color(WHITE);
  525. #endif
  526.     bgntmesh();
  527. #ifdef RGB_MODE
  528.     RGBcolor(0, 0, 255);
  529. #endif
  530.     v[0] = 0.5 - 0.17;
  531.     v[1] = 0.01;
  532.     v2f(v);
  533.     v[1] = 0.03;
  534.     v2f(v);
  535. #ifdef RGB_MODE
  536.     RGBcolor(speed255, 0, 255-speed255);
  537. #endif
  538.     v[0] = 0.5 - 0.17 + speed*0.34;
  539.     v[1] = 0.01;
  540.     v2f(v);
  541.     v[1] = 0.03 + speed*0.03;
  542.     v2f(v);
  543.     endtmesh();
  544.  
  545.     /* draw up our own colour patch */
  546. #ifdef RGB_MODE
  547.     cpack(trail_col[good->trail_colour]);
  548. #else
  549.     color(trail_col[good->trail_colour]);
  550. #endif
  551.     bgntmesh();
  552.     v[0] = 0.5 - 0.165;
  553.     v[1] = 0.07;
  554.     v2f(v);
  555.     v[0] = 0.5 - 0.125;
  556.     v[1] = 0.125;
  557.     v2f(v);
  558.     v[0] = 0.5 + 0.165;
  559.     v[1] = 0.07;
  560.     v2f(v);
  561.     v[0] = 0.5 + 0.125;
  562.     v[1] = 0.125;
  563.     v2f(v);
  564.     endtmesh();
  565.  
  566.     /* write up a couple of score numbers */
  567. #ifdef RGB_MODE
  568.     cpack(0);
  569. #else
  570.     color(BLACK);
  571. #endif
  572.     sprintf(junk, "%d", pts);
  573.     cmov2(0.5 - 0.12, 0.08);
  574.     charstr(junk);
  575.  
  576. #if 0
  577.     /* tmp @@@ some kill numbers */
  578.     sprintf(junk, "b %d t %d", big_kills, trail_kills);
  579.     cmov2(0.5, 0.08);
  580.     charstr(junk);
  581. #endif
  582.  
  583.     /*
  584.      * draw a flashing proximity square if we're < some dist
  585.      * from a collision
  586.      */
  587.     if (min < 0.05*DIM) {
  588.         min_colour++;
  589.         min_colour %= 2;
  590.         if (min_colour)
  591. #ifdef RGB_MODE
  592.         cpack(0);
  593.         else
  594.         cpack(0x0000ff);
  595. #else
  596.         color(BLACK);
  597.         else
  598.         color(RED);
  599. #endif
  600.         bgntmesh();
  601.         v[0] = 0.52 + 0.03;
  602.         v[1] = 0.095 - 0.015;
  603.         v2f(v);
  604.         v[0] = 0.62 - 0.03;
  605.         v2f(v);
  606.         v[0] = 0.52 + 0.01;
  607.         v[1] = 0.095 - 0.012;
  608.         v2f(v);
  609.         v[0] = 0.62 - 0.01;
  610.         v2f(v);
  611.         v[0] = 0.52;
  612.         v[1] = 0.095;
  613.         v2f(v);
  614.         v[0] = 0.62;
  615.         v2f(v);
  616.         v[0] = 0.52 + 0.01;
  617.         v[1] = 0.095 + 0.012;
  618.         v2f(v);
  619.         v[0] = 0.62 - 0.01;
  620.         v2f(v);
  621.         v[0] = 0.52 + 0.03;
  622.         v[1] = 0.095 + 0.015;
  623.         v2f(v);
  624.         v[0] = 0.62 - 0.03;
  625.         v2f(v);
  626.         endtmesh();
  627.     }
  628.     }
  629.  
  630.     /* write up a list of players */
  631.     write_player_list(0.01, 0.97, -0.03);
  632.  
  633.     /* write a left/right/rear indicator if necessary */
  634. #ifdef RGB_MODE
  635.     cpack(0xffffff);
  636. #else
  637.     color(WHITE);
  638. #endif
  639.     cmov2(0.9, 0.95);
  640.     switch (look_offset) {
  641.     case 1:
  642.         charstr("left");
  643.         break;
  644.     case 2:
  645.         charstr("rear");
  646.         break;
  647.     case 3:
  648.         charstr("right");
  649.         break;
  650.     }
  651.  
  652.     if (help_mode) instructions();
  653.  
  654.     /* restore normal settings */
  655.     zbuffer(TRUE);
  656.     set_win_coords();
  657. }
  658.  
  659.  
  660. void set_win_coords(void) {
  661.     window(-2.0, 2.0, -1.0, 1.0, 1.0, DIM*3.0);
  662. }
  663.  
  664.  
  665. /* Open graphics window*/
  666. void openwindow(void) {
  667.     keepaspect(2, 1);
  668.     minsize(600, 300);
  669.     winopen("Cycles");
  670.  
  671. #ifdef RGB_MODE
  672.     RGBmode();
  673. #else
  674.     cmode();
  675.     mapcolor(GREY25,  25, 25, 25);
  676.     mapcolor(GREY50,  50, 50, 50);
  677.     mapcolor(trail_col[TRAIL0],   0, 255, 255);
  678.     mapcolor(trail_col[TRAIL1], 255,   0, 255);
  679.     mapcolor(trail_col[TRAIL2], 255, 255,   0); /* @@@ this is bad, rgb or restore */
  680.     mapcolor(trail_col[TRAIL3],   0, 255,  86);
  681.     mapcolor(trail_col[TRAIL4],   0,  86, 255);
  682.     mapcolor(trail_col[TRAIL5], 255,   0, 86);
  683. #endif
  684.  
  685.     doublebuffer();
  686.     gconfig();
  687.  
  688.     zbuffer(TRUE);
  689. #ifdef SHADING
  690.     shademodel(GOURAUD);
  691. #else
  692.     shademodel(FLAT); /* GOURAUD for trail shading */
  693. #endif
  694.  
  695.     mmode(MVIEWING);
  696.     set_win_coords();
  697. #ifdef RGB_MODE
  698.     cpack(0x0);
  699. #else
  700.     color(BLACK);
  701. #endif
  702.     clear();
  703.     zclear();
  704.     swapbuffers();
  705.  
  706.     qdevice(LEFTMOUSE);
  707.     qdevice(RIGHTMOUSE);
  708.     qdevice(HKEY);
  709.     qdevice(ESCKEY);
  710.     qdevice(SPACEKEY);
  711.     qdevice(LEFTARROWKEY);
  712.     qdevice(RIGHTARROWKEY);
  713. }
  714.  
  715.  
  716. void instructions(void) {
  717.     zbuffer(FALSE);
  718.     mmode(MVIEWING);
  719.     ortho2(0.0, 1.0, 0.0, 1.0);
  720.  
  721. #ifdef RGB_MODE
  722.     cpack(0xffffff);
  723. #else
  724.     color(WHITE);
  725. #endif
  726.     /* also found in screens.c */
  727.     cmov2(0.2, 0.9);
  728.     charstr("turn  - left and right mouse buttons");
  729.     cmov2(0.2, 0.85);
  730.     charstr("speed - hold down A or middle mouse to");
  731.     cmov2(0.2, 0.8);
  732.     charstr("        accelerate. lift off to slow down");
  733.     cmov2(0.2, 0.75);
  734.     charstr("jump  - space bar\n");
  735.     cmov2(0.2, 0.7);
  736.     charstr("look  - use left and right arrows to look around");
  737.     cmov2(0.2, 0.65);
  738.     charstr("help  - H toggles these instructions");
  739.     cmov2(0.2, 0.6);
  740.     charstr("quit  - ESC key");
  741.  
  742.     zbuffer(TRUE);
  743.     set_win_coords();
  744. }
  745.  
  746.  
  747. void draw_all_2d(void) {
  748.     int i, j, level, segment;
  749.     float v[3];
  750.     CYCLE *C;
  751.     static float z_rot = 0;
  752.  
  753.     z_rot += speed_fac;
  754.     if (z_rot > 360.0) z_rot -= 360.0;
  755.  
  756.     pushmatrix();
  757.     rot(75, 'x');
  758.     rot(z_rot, 'z');
  759.  
  760.     for (level = 0; level < LEVELS; level++) {
  761.  
  762.     zbuffer(TRUE);
  763.     v[2] = level*0.5*DIM;
  764.  
  765.     /* draw black platform */
  766. #ifdef RGB_MODE
  767.     cpack(0);
  768. #else
  769.     color(BLACK);
  770. #endif
  771.     bgntmesh();
  772.     v[0] = -DIM;
  773.     v[1] = -DIM;
  774.     v3f(v);
  775.     v[1] = DIM;
  776.     v3f(v);
  777.     v[0] = DIM;
  778.     v[1] = -DIM;
  779.     v3f(v);
  780.     v[1] = DIM;
  781.     v3f(v);
  782.     endtmesh();
  783.  
  784.     zbuffer(FALSE);
  785.  
  786.     /* border in level colours */
  787. #ifdef RGB_MODE
  788.     cpack(level_col[level]);
  789. #else
  790.     color(level_col[level]);
  791. #endif
  792.     bgnclosedline();
  793.     v[0] = -DIM;
  794.     v[1] = -DIM;
  795.     v3f(v);
  796.     v[1] = DIM;
  797.     v3f(v);
  798.     v[0] = DIM;
  799.     v3f(v);
  800.     v[1] = -DIM;
  801.     v3f(v);
  802.     endclosedline();
  803.  
  804.     /* draw trails */
  805.     for (j = 0; j < CYCLES; j++) {
  806.         C = &bike[j];
  807.  
  808.         if (C->falling == 0)
  809. #ifdef RGB_MODE
  810.         cpack(trail_col[C->trail_colour]);
  811.         else
  812.         cpack(0xffffff);
  813. #else
  814.         color(trail_col[C->trail_colour]);
  815.         else
  816.         color(WHITE);
  817. #endif
  818.         if (used[j] && C->alive && j != good->id && C->falling >= 0) {
  819.         /*
  820.          * all but 1st trail element
  821.          */
  822.         segment = 0;
  823.         i = C->trail_ptr;
  824.         do {
  825.             if (C->trail[i].level == level) {
  826.             if (!segment) {
  827.                 segment = 1;
  828.                 bgnline();
  829.             }
  830.             v[0] = C->trail[i].x;
  831.             v[1] = C->trail[i].z;
  832.             v3f(v);
  833.             }
  834.             else if (segment) {
  835.             segment = 0;
  836.             endline();
  837.             }
  838.             i = (i - 1 + TRAIL_LENGTH) % TRAIL_LENGTH;
  839.         } while(i != C->trail_ptr && C->trail[i].level != -1);
  840.         if (segment) endline();
  841.  
  842.         if (C->level == level) {
  843.             /*
  844.              * 1st trail: from bike to 1st corner
  845.              */
  846.             i = C->trail_ptr;
  847.             if (MAX(ABS(C->trail[i].x - C->origin.x), ABS(C->trail[i].z - C->origin.z)) > CYCLE_TAIL) {
  848.             bgnline();
  849.             v[0] = C->trail[i].x;
  850.             v[1] = C->trail[i].z;
  851.             v3f(v);
  852. #if defined(SHADING) && defined(RGB_MODE)
  853.             cpack(0xffffff);
  854. #endif
  855.             v[0] = C->origin.x - CYCLE_TAIL*vec[C->vec_ptr][0];
  856.             v[1] = C->origin.z - CYCLE_TAIL*vec[C->vec_ptr][1];
  857.             v3f(v);
  858.             endline();
  859.             }
  860.         }
  861.         }
  862.         /* draw dot for jumping bike */
  863.         if (C->level == level && used[j] && C->alive && j != good->id && C->jump) {
  864. #ifdef RGB_MODE
  865.         cpack(0xffffff);
  866. #else
  867.         color(WHITE);
  868. #endif
  869.         v[0] = C->origin.x;
  870.         v[1] = C->origin.z;
  871.         pushmatrix();
  872.         translate(0.0, 0.0, v[2]);
  873.         circf(v[0], v[1], 3);
  874.         popmatrix();
  875.         }
  876.     }
  877.     }
  878.  
  879.     popmatrix();
  880. }
  881.